package lol.clann.minecraft.springboot.plugin.core.database.datasource;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.pool.DruidDataSource;
import com.ruoshui.utils.jdbc.druid.sql.logger.SqlLogFilter;
import lol.clann.minecraft.springboot.api.context.SpringContext;
import lol.clann.minecraft.springboot.plugin.core.service.DDLManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author pyz
 * @date 2019/6/25 9:50 PM
 */
@Slf4j
@Component
@ConditionalOnProperty(name = "springbootplugin.datasource.enable", havingValue = "true")
public class DataSourceProcesser implements BeanPostProcessor, Ordered {

    private static DruidDataSource dataSource;
    private static DataSourceConfig config;

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof DataSourceConfig) {
            config = (DataSourceConfig) bean;
        } else if (bean instanceof DruidDataSource) {
            dataSource = (DruidDataSource) bean;
//            配置sql日志
            refresh();
        } else if (bean instanceof SqlSessionFactory) {
//          在SqlSessionFactory准备好后,执行ddl
            GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
            beanDefinition.setBeanClass(DDLManager.class);
            SpringContext.registerBeanDefinition("ddlManager", beanDefinition);
            DDLManager ddlManager = SpringContext.getBean("ddlManager");
//                执行ddl
            ddlManager.ddl();
        }
        return bean;
    }

    static void refresh() {
        if (dataSource == null) {
            return;
        }
        if (config.isLogsql()) {
            enableLogFilter();
            LOGGER.info("SQL日志已启用");
        } else {
            disableLogFilter();
            LOGGER.info("SQL日志已停用");
        }
    }

    private static void enableLogFilter() {
        List<Filter> filters = dataSource.getProxyFilters();
        if (filters == null) {
            return;
        }
        for (Filter filter : filters) {
            if (filter instanceof SqlLogFilter) {
                ((SqlLogFilter) filter).setEnable(true);
                return;
            }
        }
    }

    private static void disableLogFilter() {
        List<Filter> filters = dataSource.getProxyFilters();
        if (filters == null) {
            return;
        }
        for (Filter filter : filters) {
            if (filter instanceof SqlLogFilter) {
                ((SqlLogFilter) filter).setEnable(false);
                return;
            }
        }
    }

    @Override
    public int getOrder() {
        return 1001;
    }
}
